<?php

namespace app\admin\model\kuerp;

use app\admin\model\Admin;
use app\admin\model\department\Admin as DepartmentAdmin;
use addons\kuerp\model\Flows;
use think\Model;
use traits\model\SoftDelete;
use Exception;
use think\Db;

class Expense extends Model
{

    use SoftDelete;
    // 表名
    protected $name = 'kuerp_expense';
    
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';

    // 追加属性
    protected $append = [
        'income_month_text',
        'start_time_text',
        'end_time_text',
        // 'pay_time_text',
        'createtime_text',
        // 'updatetime_text',
        // 'delete_time_text',
        'check_time_text'
    ];
    

    public function getCheckStatusList()
    {
        return ['0' => __('Check_status 0'), '1' => __('Check_status 1'), '2' => __('Check_status 2'), '3' => __('Check_status 3'), '4' => __('Check_status 4')];
    }
    public function getCheckStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['check_status']) ? $data['check_status'] : '');
        $list = $this->getCheckStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }



    public function getStartTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['start_time']) ? $data['start_time'] : '');
        return is_numeric($value) ? date("Y-m-d", $value) : $value;
    }


    public function getEndTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['end_time']) ? $data['end_time'] : '');
        return is_numeric($value) ? date("Y-m-d", $value) : $value;
    }


    public function getPayTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['pay_time']) ? $data['pay_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getCreatetimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['createtime']) ? $data['createtime'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getUpdatetimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['updatetime']) ? $data['updatetime'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getDeletetimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['deletetime']) ? $data['deletetime'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getCheckTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['check_time']) ? $data['check_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }
    public function getIncomeMonthTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['income_month']) ? $data['income_month'] : '');
        return is_numeric($value) ? date("Y-m", $value) : $value;
    }

    protected function setStartTimeAttr($value)
    {
        return $value === '' ? 0 : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    protected function setEndTimeAttr($value)
    {
        return $value === '' ? 0 : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    protected function setPayTimeAttr($value)
    {
        return $value === '' ? 0 : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    protected function setCreatetimeAttr($value)
    {
        return $value === '' ? 0 : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    protected function setUpdatetimeAttr($value)
    {
        return $value === '' ? 0 : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    protected function setCheckTimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }
    protected function setIncomeMonthAttr($value)
    {
        return $value === '' ? 0 : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    public function addExpense($params)
    {
        $params['check_status'] = $params['check_status'] ?? 1;
        $infos = [];
        if ($params['info']) {
            $infos = $params['info'];
            unset($params['info']);
        }
        $admin = Admin::info();
        $params['admin_id'] = $admin->id;
        $params['did'] = 0;
        //获取当前用户所在部门
        $department_ids = DepartmentAdmin::getDepartmentIds($admin->id);
        $params['department_ids'] = $department_ids ? $department_ids[0] : 0;
        //是否在审核流程中
        //获取审批流程
        $flows = Db::name('flows')->where('relation_type', 'expense')->where('status', 1)->find();
        if (!empty($flows)){
            $flows['flow_items'] = json_decode($flows['flow_items'], true);
            //判断流程中是否有当前用户审核
            $examine_index = 0;
            foreach ($flows['flow_items'] as $key => $value) {
                if (in_array($params['admin_id'], explode(',',$value['admin_id'])) ) {
                    $examine_index = $key + 1;
                    // break;
                }
            }
            $params['check_flow_id'] = $flows['id'];
            $params['check_step_sort'] = $examine_index;
        }
        
        $expense = new self;

        $result = $expense->allowField(true)->save($params);
        if (!$result) {
            throw new Exception($expense->getError());
        }
        $lastId = $expense->getLastInsID();
        $addInfos = [];
        $cost = 0;
        foreach ($infos as $v) {
            if (!$v['total_money'] || $v['total_money'] <= 0) {
                throw new Exception('合计金额必须大于0');
            }
            $v['expense_id'] = $lastId;
            $v['admin_id'] = $admin->id;
            $v['expense_time'] = strtotime($v['expense_time']);
            $v['createtime'] = time();
            $v['updatetime'] = time();
            $addInfos[] = $v;
            $cost += (float)$v['total_money'];
        }
        if ($addInfos) {
            $infoModel = new ExpenseInfo();
            $res = $infoModel->allowField(true)->insertAll($addInfos);
            if (!$res) {
                throw new Exception($infoModel->getError());
            }
        }
        $this->where(['id' => $lastId])->update(['cost' => $cost]);
        if ($params['check_status'] == 1) {
            $flow = Flows::getFlowByTypes(Flows::EXPENSE_STATUS);
            //发送审批通知
            Flows::sendStepRecord($flow, Flows::EXPENSE_STATUS, $lastId);
        }
        return $lastId;
    }

    public function editExpense($params, $row)
    {
        $infos = [];
        if ($params['info']) {
            $infos = $params['info'];
            unset($params['info']);
        }
        if($row['check_status'] != 2){
            //获取审批流程
            $flows = Db::name('flows')->where('relation_type', 'expense')->where('status', 1)->find();
            if (!empty($flows)){
                $flows['flow_items'] = json_decode($flows['flow_items'], true);
                //判断流程中是否有当前用户审核
                $examine_index = 0;
                foreach ($flows['flow_items'] as $key => $value) {
                    if (in_array($row['admin_id'], explode(',',$value['admin_id'])) ) {
                        $examine_index = $key + 1;
                        // break;
                    }
                }
                // $params['check_flow_id'] = $flows['id'];
                $params['check_step_sort'] = $examine_index;
            }
            $params['check_status'] = $params['check_status'] ?? 1;
            // $params['check_step_sort'] = 0;
            $params['check_uids'] = '';
            $params['check_time'] = 0;
            $params['check_remark'] = '';
            $params['updatetime'] = time();
        }

        $expense = new self;
        // 调用当前模型对应的User验证器类进行数据验证
        $result = $expense->isUpdate(true)->allowField(true)->save($params, ['id' => $params['id']]);
        if (false === $result) {
            // 验证失败 输出错误信息
            throw new Exception($expense->getError());
        }
        $infoModel = new ExpenseInfo();
        $dbIds = $infoModel->where(['expense_id'=> $params['id']])->column('id');
        //差集 不存在的删除
        $diff_ids = array_diff($dbIds, (array)array_column($infos, 'id'));
        $addInfos = [];
        $cost = 0;
        foreach ($infos as $v) {
            if (!$v['total_money'] || $v['total_money'] <= 0) {
                throw new Exception('合计金额必须大于0');
            }
            //没有id 或者 id存在但存在于数据库
            if(empty($v['id']) || (!empty($v['id']) && !in_array($v['id'], $dbIds))) {
                $v['createtime'] = time();
                if (isset($v['id'])) unset($v['id']);
                // unset($v['id']);
            }
            $v['expense_id'] = $params['id'];
            $v['admin_id'] = $row['admin_id'];
            $v['expense_time'] = strtotime($v['expense_time']);
            $v['updatetime'] = time();
            $addInfos[] = $v;
            $cost += (float)$v['total_money'];
        }
        
        // $infoModel->where(['expense_id' => $params['id']])->delete();
        if ($addInfos) {
            $res = $infoModel->allowField(true)->saveAll($addInfos);
            if (!$res) {
                throw new Exception($infoModel->getError());
            }
        }
        if ($diff_ids) {
            $res = $infoModel->where(['id'=> ['in', $diff_ids]])->delete();
        }
        $this->where(['id' => $params['id']])->update(['cost' => $cost]);
        return true;
    }

    public function getInfo($id)
    {
        $info = $this->where(['id' => $id])->find();
        //获取附件
        if (!empty($info)) {
            $files = explode(',', $info['file_ids']);
            $fileList = [];
            foreach($files as $file) {
                if (empty($file)) { continue; }
                $nameParts = explode('.', $file);
                $ext = end($nameParts);
                $fileList[] = [
                    'file_path' => cdnurl($file),
                    'ext' => $ext,
                    'type' => in_array(strtolower($ext), ['png','jpg','jpeg','gif','bmp','webp']) ? 'image':'file'
                ];
            }
            // $fileList = Db::name('kuerp_file')->where(['file_path' => ['in', $files]])->group('file_path')->column('id,types,name,size,file_path,createtime', 'file_path');
            // foreach ($fileList as $k => &$v) {
            //     $v['size'] = format_bytes($v['size']);
            //     $v['createtime'] = date('Y-m-d H:i:s', $v['createtime']);
            //     $nameParts = explode('.', $v['name']);
            //     $v['ext'] = end($nameParts);
            // }
            $info['file_list'] = $fileList;

        }
        return $info;
    }

    public function admin()
    {
        return $this->belongsTo(Admin::class, 'admin_id', 'id');
    }

    public function expenseinfo() {
		return $this->hasMany(ExpenseInfo::class, 'expense_id', 'id')->field('*');
	}

}
